package com.workflow.generator;

import java.util.List;
import java.util.Set;

import org.jgrapht.Graph;
import org.jgrapht.alg.DijkstraShortestPath;
import org.jgrapht.alg.KruskalMinimumSpanningTree;
import org.jgrapht.graph.DefaultWeightedEdge;

public class PathSearchingEngines {

	private final double TIME_DELAY = 6.08934554;

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List getShortestPath(Graph graph, Object sourceVertex,
			Object destinationVertex) {
		List path = DijkstraShortestPath.findPathBetween(graph, sourceVertex,
				destinationVertex);

		return path;

	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List getDTCBasedPath(Graph graph, Object sourceVertex,
			Object destinationVertex) {
		List path = DijkstraShortestPath.findPathBetween(graph, sourceVertex,
				destinationVertex);
		return path;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public double getGreedyCost(Graph graph) {
		KruskalMinimumSpanningTree<String, DefaultWeightedEdge> krutree = new KruskalMinimumSpanningTree<String, DefaultWeightedEdge>(
				graph);
		double cost = krutree.getSpanningTreeCost();
		return cost;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Set<DefaultWeightedEdge> getMinimumSpanningEdges(Graph graph) {
		KruskalMinimumSpanningTree<String, DefaultWeightedEdge> krutree = new KruskalMinimumSpanningTree<String, DefaultWeightedEdge>(
				graph);

		return krutree.getEdgeSet();
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Double getDistance(Graph graph, Object sourceVertex,
			Object destinationVertex) {
		// Get the shortest path
		List paths = getShortestPath(graph, sourceVertex, destinationVertex);
		Double distance = 0.0;
		if (paths != null) {
			for (Object path : paths) {
				DefaultWeightedEdge edge = (DefaultWeightedEdge) path;
				distance += graph.getEdgeWeight(edge);
			}
		}
		return distance;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public int isNeighbourOf(Graph graph, Object sourceVertex,
			Object destinationVertex) {
		boolean exists = graph.containsEdge(sourceVertex, destinationVertex);
		if (exists || sourceVertex.equals(destinationVertex))
			return 1;
		else
			return 0;
	}

	public Double getTimeDelay(Double distance) {
		return (distance / TIME_DELAY);
	}

	// Alternate path engine
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Graph alternatePathGraph(Graph graph, Object sourceVertex,
			Object destinationVertex) {

		Graph alternatePathGraph = graph;
		List path = getShortestPath(graph, sourceVertex, destinationVertex);
		if (path != null) {
			alternatePathGraph.removeAllEdges(path);
		}
		return alternatePathGraph;
	}
}
